package com.ebt.m.proposal_v2.ui.view;

import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;

import com.ebt.m.R;
import com.ebt.m.proposal_v2.ProposalConstant;
import com.ebt.m.proposal_v2.base.Constant;
import com.ebt.m.proposal_v2.bean.ApplicantEntity;
import com.ebt.m.proposal_v2.bean.ArgProductOption;
import com.ebt.m.proposal_v2.bean.InsuranceCalculator;
import com.ebt.m.proposal_v2.bean.InsuranceEntity;
import com.ebt.m.proposal_v2.bean.InsuredEntity;
import com.ebt.m.proposal_v2.bean.event.NormalRiskCompleteEvent;
import com.ebt.m.proposal_v2.event.ApplicantChangedEvent;
import com.ebt.m.proposal_v2.event.CancelCalculating;
import com.ebt.m.proposal_v2.helper.PickerHelper;
import com.ebt.m.proposal_v2.helper.ThemeHelper;
import com.ebt.m.proposal_v2.interfaces.OnRxClickListener;
import com.ebt.m.proposal_v2.ui.function.ExemptDao;
import com.ebt.m.proposal_v2.ui.function.ExemptTask;
import com.ebt.m.proposal_v2.ui.function.InsuranceCellViewUpdater;
import com.ebt.m.proposal_v2.utils.RxUtils;
import com.ebt.m.proposal_v2.utils.SharePrefrenceUtils;
import com.ebt.m.proposal_v2.widget.base.CompatLinearLayout;
import com.ebt.m.proposal_v2.widget.dialog.EBTBottomWebDialog;
import com.ebt.m.proposal_v2.widget.view.InsuranceCellView;
import com.ebt.m.proposal_v2.widget.view.ProposalHeader;
import com.ebt.m.proposal_v2.widget.view.ProposalHelper;
import com.ebt.m.commons.utils.Logger;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.util.ArrayList;
import java.util.List;

import butterknife.BindView;

import static com.ebt.m.proposal_v2.ProposalConstant.ACTION_PRODUCT_ADD;
import static com.ebt.m.proposal_v2.ProposalConstant.ACTION_PRODUCT_CLEAR;
import static com.ebt.m.proposal_v2.ProposalConstant.ACTION_PRODUCT_DELETE;
import static com.ebt.m.proposal_v2.ProposalConstant.ACTION_PRODUCT_KEEP;
import static com.ebt.m.proposal_v2.ProposalConstant.EXEMPTION_TYPE_APPLICANT;
import static com.ebt.m.proposal_v2.ProposalConstant.PRODUCT_ATTATCH;
import static com.ebt.m.proposal_v2.ProposalConstant.PRODUCT_MAIN;
import static com.ebt.m.proposal_v2.ProposalConstant.RISK_TYPE_EXEMPT;

/**
 * 险种信息（包括主险与附加险）
 *
 * @author archer.qi
 * Created on 2017/5/11.
 */
public class InsuranceView extends CompatLinearLayout {

    @BindView(R.id.insurance_header)
    ProposalHeader proposalHeader;
    @BindView(R.id.container)
    LinearLayout container;
    @BindView(R.id.actionAddOtherInsurance)
    RelativeLayout addOtherInsurance;
    @BindView(R.id.btnAddInsurance)
    Button addMainOrAdditional;
    @BindView(R.id.helperTip)
    ProposalHelper proposalHelper;
    /**
     * 被保人
     */
    private InsuredEntity mInsuredPerson;
    /**
     * 投保人
     */
    private ApplicantEntity mApplicantPerson;
    private OnProductAddListener mOnProductAddListener;
    private OnProductChangedListener mOnChangedListener;
    private EBTBottomWebDialog mOptionWebDialog;
    /**
     * 是否是批量导入
     */
    private boolean isImportByBatch;
    /**
     * 用于处理普通附加险的更新，更新完成后，发事件，开始更新豁免险
     */
    private InsuranceCellViewUpdater mInsuranceCellViewUpdater;

    public InsuranceView(Context context) {
        super(context);
    }

    public InsuranceView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        if (!EventBus.getDefault().isRegistered(this)) {
            EventBus.getDefault().register(this);
        }
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        if (EventBus.getDefault().isRegistered(this)) {
            EventBus.getDefault().unregister(this);
        }
    }

    @Override
    protected int setContentView() {
        return R.layout.proposal_v2_insurance;
    }

    @Override
    protected void onBindView() {
        initHeader();
        initListener();
        adjustAddRisk();
        updateBtnAddInsuranceState();
        mInsuranceCellViewUpdater = new InsuranceCellViewUpdater(getContext(), this);
    }

    private void initHeader() {
        proposalHeader.setTitle(R.string.proposalKeyInsurance);
        proposalHeader.hideRight();
        addOtherInsurance.setVisibility(VISIBLE);
    }

    private boolean forMoreInsuredView;

    public void setForMoreInsuredView(boolean forMoreInsuredView) {
        this.forMoreInsuredView = forMoreInsuredView;
        updateBtnAddInsuranceState();
    }

    private void updateBtnAddInsuranceState() {
        if (addMainOrAdditional != null && forMoreInsuredView) {
            if (true) {
                //本被保人第一次添加 显示添加附加险
                addMainOrAdditional.setText(R.string.button_addAdditional0);
            } else {
                //本被保人第二次添加，显示继续添加附加险
                addMainOrAdditional.setText(R.string.button_addAdditional);
            }
            addMainOrAdditional.setTag(1);
        }
    }

    private void setHelperView() {
        boolean hasHelper = SharePrefrenceUtils.getDefault().getBoolean(Constant.SP_PROPOSAL_MAIN_TIP, true);
        if (hasHelper) {
            showProposalHelper();

            proposalHelper.setMessage(ThemeHelper.getString(getViewContext(), R.string.insurance_tip));
            proposalHelper.onDeleteListener(v -> {
                SharePrefrenceUtils.getDefault().putBoolean(Constant.SP_PROPOSAL_MAIN_TIP, false);
                hideProposalHelper();
            });
            /*同投保人，改为第一次新建计划书显示，之后便不再显示，设为隐藏*/
            SharePrefrenceUtils.getDefault().putBoolean(Constant.SP_PROPOSAL_MAIN_TIP, false);
        } else {
            hideProposalHelper();
        }
    }


    private void initListener() {

        RxUtils.click(addMainOrAdditional, new OnRxClickListener() {
            @Override
            public void onRxClick(View view) {
                int btnTag = (int) addMainOrAdditional.getTag();
                if (btnTag == 0) { // 添加主险
                    if (mOnProductAddListener != null) {
                        mOnProductAddListener.addMainProduct();
                    }
                }
                if (btnTag == 1) { // 添加附加险
                    if (mOnProductAddListener != null) {
                        mOnProductAddListener.addAttachProduct(getExistsAdditionalIds());
                    }
                }
            }
        });
    }

    /*
    /**
     * 判定添加主险或附加险
     */
    private void adjustAddRisk() {
        if (container == null) {
            addMain();
            return;
        }
        final int childCount = container.getChildCount();
        if (childCount <= 0) {
            addMain();
            return;
        }
        if (!hasMain()) {
            addMain();
        } else {
            addAttach();
        }
    }

    /**
     * 显示添加主险
     */
    private void addMain() {
        addMainOrAdditional.setText(getString(R.string.button_addMain));
        addMainOrAdditional.setTag(0);
    }

    /**
     * 显示添加附加险
     */
    private void addAttach() {
        addMainOrAdditional.setText(getString(R.string.button_addAdditional));
        addMainOrAdditional.setTag(1);
    }

    /**
     * 创建一个险种View
     *
     * @param data
     * @return
     */
    private InsuranceCellView createCellView(InsuranceEntity data) {
        if (data == null) {
            return null;
        }
        InsuranceCellView cellView = new InsuranceCellView(getViewContext(), this);
        cellView.setFragmentManager(getFragmentManager());
        cellView.setInsuredEntity(getInsuredPerson());//初始化被保人
        cellView.setData(data);//初始化险种数据

        cellView.setActionListener(new InsuranceCellView.OnActionListener() {
            //点击计算器
            @Override
            public void onEdit(InsuranceCellView view) {
                // ************* 主险或附加险编辑 ************* /
                if (container == null || view == null || view.getData() == null) {
                    return;
                }
                if (containsChild(view)) {
                    mOptionWebDialog = PickerHelper.showProposalCalculator(getFragmentManager(),
                            createProductOptionArg(view.getData()));
                    mOptionWebDialog.addProductSetListener(new EBTBottomWebDialog.OnProductSetListener() {
                        @Override
                        public void onProductSet(InsuranceCalculator calculator) {
                            /* 编辑主险或附加险返回*/
                            updateOnProductSet(view, calculator);
                        }
                    });
                }
            }

            @Override
            public void onDelete(InsuranceCellView view) {
                // ************* 主险或附加险删除 ************* /
                if (container == null || view == null || view.getData() == null) {
                    return;
                }
                if (containsChild(view)) {
                    boolean isMain = view.getData().isMain();
                    if (isMain) {
                        onMainSetChanged(view.getData(), 1);
                        if (mOnProductAddListener != null) {
                            mOnProductAddListener.deleteMainProduct();
                        }
                    } else {
                        onAttachSetChanged(view, view.getData(), 1);
                    }
                }
            }
        });
        return cellView;
    }

    private void updateOnProductSet(InsuranceCellView view, InsuranceCalculator calculatorResult) {
        if (calculatorResult != null) {
            InsuranceEntity data1 = view.getData();
            if (data1 != null) {
                if (calculatorResult.optPremium != null) {
                    data1.premium = calculatorResult.optPremium;
                }
                if (calculatorResult.optCoverage != null) {
                    data1.coverage = calculatorResult.optCoverage;
                }
                if (calculatorResult.optCoveragePeriod != null) {
                    data1.coveragePeriod = calculatorResult.optCoveragePeriod;
                }
                if (calculatorResult.optPaymentPeriod != null) {
                    data1.paymentPeriod = calculatorResult.optPaymentPeriod;
                }
                data1.addExtraData(calculatorResult.mOptionList);
                view.setData(data1);
                if (mOnChangedListener != null) {
                    mOnChangedListener.onProductChanged(data1, data1.isMain, ProposalConstant.ACTION_PRODUCT_EDIT);
                }
            }
        }
    }

    /**
     * 生成一个计算器编辑参数
     *
     * @param product
     * @return
     */
    private ArgProductOption createProductOptionArg(InsuranceEntity product) {
        if (product == null) {
            return null;
        }
        ArgProductOption arg = new ArgProductOption();
        arg.productId = product.productId + "";
        arg.productName = product.productName;

        if (product.riskType == RISK_TYPE_EXEMPT && product.getExemptionType() == EXEMPTION_TYPE_APPLICANT) {
            // 如果是豁免险，且豁免投保人
            arg.age = mApplicantPerson == null ? "30" : mApplicantPerson.age + "";
            arg.sex = mApplicantPerson == null ? "1" : mApplicantPerson.sex + "";
            arg.profession = "1";
            arg.birthday = mApplicantPerson == null ? "" : mApplicantPerson.birthday;
        } else {
            // 如果是豁免险，且豁免被保人；或者不是豁免险
            arg.age = mInsuredPerson == null ? "30" : mInsuredPerson.age + "";
            arg.sex = mInsuredPerson == null ? "1" : mInsuredPerson.sex + "";
            arg.profession = mInsuredPerson == null ? "1" : mInsuredPerson.profession + "";
            arg.birthday = mInsuredPerson == null ? "" : mInsuredPerson.birthday;
        }

        if (product.riskType == RISK_TYPE_EXEMPT) {
            // 添加豁免险标识
            arg.isExemptRisk = true;
        }

        arg.coverage = product == null ? null : product.coverage;
        arg.premium = product == null ? null : product.premium;
        arg.coveragePeriod = product == null ? null : product.coveragePeriod;
        arg.paymentPeriod = product == null ? null : product.paymentPeriod;

        arg.extraOptions = product == null ? null : product.extraData;

        return arg;
    }


    /**
     * 主险添加或删除
     *
     * @param data
     * @param actionFlag
     */
    private void onMainSetChanged(InsuranceEntity data, int actionFlag) {
        int action = ACTION_PRODUCT_KEEP;
        if (actionFlag == 0) { // 添加主险
            InsuranceCellView cellView = createCellView(data);
            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
            container.addView(cellView, params);
            setHelperView();
            action = ACTION_PRODUCT_ADD;
        }
        if (actionFlag == 1) { // 删除主险
            container.removeAllViews();
            container.requestLayout();
            hideProposalHelper();
            action = ACTION_PRODUCT_DELETE;
        }
        if (data.isMain()) {
            adjustAddRisk();
        }
        if (mOnChangedListener != null) {
            mOnChangedListener.onProductChanged(data, PRODUCT_MAIN, action);
        }
    }

    /**
     * 附加险添加或删除
     *
     * @param view
     * @param data
     * @param actionFlag
     */
    private void onAttachSetChanged(InsuranceCellView view, InsuranceEntity data, int actionFlag) {
        int action = ACTION_PRODUCT_KEEP;
        // 添加附加险
        if (actionFlag == 0) {
            data.isMain = 0;
            InsuranceCellView cellView = createCellView(data);
            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
            container.addView(cellView, params);
            action = ACTION_PRODUCT_ADD;
        } else if (actionFlag == 1) {
            // 删除附加险
            container.removeView(view);
            container.requestLayout();
            action = ACTION_PRODUCT_DELETE;
        }
        if (mOnChangedListener != null) {
            if (action == ACTION_PRODUCT_DELETE) {
                mOnChangedListener.onProductChanged(data, PRODUCT_ATTATCH, action);
            } else if (action == ACTION_PRODUCT_ADD) {
                // 批量导入时， 单次变更不监听
                if (!isImportByBatch) {
                    mOnChangedListener.onProductChanged(data, PRODUCT_ATTATCH, action);
                }
            }
        }
    }

    /**
     * 是否包含子View
     *
     * @param view
     * @return
     */
    private boolean containsChild(InsuranceCellView view) {
        if (view == null || container == null || view.getData() == null) {
            return false;
        }

        for (int i = 0, length = container.getChildCount(); i < length; i++) {
            View childView = container.getChildAt(i);
            if (childView != null && childView instanceof InsuranceCellView) {
                InsuranceCellView cellView = (InsuranceCellView) childView;
                InsuranceEntity cellData = cellView.getData();
                if (cellData != null && cellData.productId == view.getData().productId) {
                    return true;
                }
            }
        }
        return false;
    }

    private void hideProposalHelper() {
        if (proposalHelper != null && proposalHelper.getVisibility() == VISIBLE) {
            proposalHelper.setVisibility(GONE);
        }
    }

    private void showProposalHelper() {
        if (proposalHelper != null) {
            proposalHelper.setVisibility(VISIBLE);
            proposalHelper.setDirectRightMargin(36);
        }
    }

    // ************************ 公用调用方法 ************************* //

    /**
     * 获取容器
     *
     * @return
     */
    public LinearLayout getContainer() {
        return container;
    }

    /**
     * 获取已经添加的附加险ids
     *
     * @return
     */
    //获取附加险id
    public ArrayList<String> getExistsAdditionalIds() {
        if (container == null) {
            return null;
        }
        ArrayList<String> ids = new ArrayList<>();
        final int count = container.getChildCount();
        for (int i = 0; i < count; i++) {
            View childView = container.getChildAt(i);
            if (childView != null && childView instanceof InsuranceCellView) {
                InsuranceCellView cellView = (InsuranceCellView) childView;
                if (cellView.getData() != null && !cellView.getData().isMain()) {
                    ids.add(cellView.getData().productId + "");
                }
            }
        }
        return ids;
    }

    public ArrayList<InsuranceCellView> getInsuranceCellViews() {
        if (container == null) {
            return null;
        }
        ArrayList<InsuranceCellView> insuranceCellViews = new ArrayList<>();
        final int count = container.getChildCount();
        for (int i = 0; i < count; i++) {
            View childView = container.getChildAt(i);
            if (childView != null && childView instanceof InsuranceCellView) {
                insuranceCellViews.add((InsuranceCellView) childView);
            }
        }
        return insuranceCellViews;
    }

    /**
     * 是否已经有主险
     *
     * @return
     */
    public boolean hasMain() {
        if (container == null || container.getChildCount() <= 0) {
            return false;
        }
        View childView = container.getChildAt(0);
        if (childView != null && childView instanceof InsuranceCellView) {
            InsuranceCellView cellView = (InsuranceCellView) childView;
            if (cellView.getData() != null && cellView.getData().isMain()) {
                return true;
            }
        }
        return false;
    }

    /**
     * 获取主险数据
     *
     * @return
     */
    public InsuranceEntity getMainProductData() {
        if (container == null || container.getChildCount() <= 0) {
            return null;
        }
        View childView = container.getChildAt(0);
        if (childView != null && childView instanceof InsuranceCellView) {
            InsuranceCellView cellView = (InsuranceCellView) childView;
            if (cellView.getData() != null && cellView.getData().isMain()) {
                return cellView.getData();
            }
        }
        return null;
    }

    /**
     * 获取所有产品数据
     *
     * @return
     */
    public List<InsuranceEntity> getProductsData() {
        if (container == null || container.getChildCount() <= 0) {
            return null;
        }
        List<InsuranceEntity> list = new ArrayList<>();
        final int count = container.getChildCount();
        for (int i = 0; i < count; i++) {
            final View childView = container.getChildAt(i);

            if (childView != null && childView instanceof InsuranceCellView) {
                InsuranceCellView cellView = (InsuranceCellView) childView;

                if (cellView.getData() != null) {
                    if (cellView.getData().isBindingMain && cellView.getData().isMain != 1) {
                        /* 如果附加险绑定了主险，则设isMain为2; ->《生成计划书的传参规定》*/
                        cellView.getData().isMain = 2;
                    }
                    cellView.getData().sort = i;
                    list.add(cellView.getData());
                }
            }
        }
        return list;
    }

    /**
     * 添加险种View
     *
     * @param data
     */
    public void addRiskView(InsuranceEntity data) {
        if (data != null) {
            if (data.isMain()) {
                onMainSetChanged(data, 0);
            } else {
                onAttachSetChanged(null, data, 0);
            }
        }
    }

    /**
     * 添加险种View
     *
     * @param list
     */
    public void addRiskViews(List<InsuranceEntity> list) {
        if (list == null || list.size() == 0) {
            return;
        }
        if (list.size() == 1) { // 单次导入
            addRiskView(list.get(0));
            return;
        }
        isImportByBatch = true;
        for (InsuranceEntity entity : list) {
            if (entity != null && entity.isMain == 1) {
                Logger.i("主险的品牌： " + entity.brandId);
            }
            addRiskView(entity);
        }
        if (mOnChangedListener != null && isImportByBatch) {
            // 批量导入最后统一添加监听
            mOnChangedListener.onProductsChanged(list);
        }
        isImportByBatch = false;
    }

    /**
     * 清空所有保险
     */
    public void clearAllProducts() {
        container.removeAllViews();
        container.requestLayout();
        hideProposalHelper();
        adjustAddRisk();
        if (mOnProductAddListener != null) {
            mOnProductAddListener.deleteMainProduct();
        }
        if (mOnChangedListener != null) {
            mOnChangedListener.onProductChanged(null, PRODUCT_MAIN, ACTION_PRODUCT_CLEAR);
        }
    }

    /**
     * 添加被保人信息
     *
     * @param insured
     */
    public void setInsuredPerson(InsuredEntity insured) {
        this.mInsuredPerson = insured;
    }

    /**
     * 添加投保人信息
     *
     * @param applicant
     */
    public void setApplicantPerson(ApplicantEntity applicant) {
        this.mApplicantPerson = applicant;
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onEventMainThread(ApplicantChangedEvent event) {
        if (event != null) {
            ApplicantEntity entity = event.applicantEntity;
            setApplicantPerson(entity);
        }
    }

    /**
     * 设置添加主附险监听
     *
     * @param listener
     */
    public void setOnProductAddListener(OnProductAddListener listener) {
        mOnProductAddListener = listener;
    }

    /**
     * 设置主附险变更监听(监控主附险添加或删除)
     *
     * @param listener
     */
    public void setOnProductChangedListener(OnProductChangedListener listener) {
        mOnChangedListener = listener;
    }

    /**
     * 判断是否有产品
     *
     * @return
     */
    public int getViewCount() {
        return container.getChildCount();
    }

    public interface OnProductAddListener {
        /**
         * 添加主险
         */
        void addMainProduct();

        /**
         * 添加附加险
         *
         * @param exists 已经添加的附加险
         */
        void addAttachProduct(ArrayList<String> exists);

        /**
         * 删除主险
         */
        void deleteMainProduct();
    }

    public interface OnProductChangedListener {
        /**
         * 单次产品变更
         *
         * @param data   改变的产品数据
         * @param isMain 0 附加险  1 主险
         * @param action 改变动作 0 清空 1 添加 2 删除 3 修改 -1不改变
         */
        void onProductChanged(InsuranceEntity data, int isMain, int action);

        /**
         * 批量附加险添加
         *
         * @param data
         */
        void onProductsChanged(List<InsuranceEntity> data);
    }

    //更新保险的信息, 更新cellview中每一个
    public void updateForCurrentInsuredPerson() {
        updateCellView(getCellViews());
    }

    private List<InsuranceCellView> getCellViews() {
        List<InsuranceCellView> cellViews = new ArrayList<>();
        if (container == null || container.getChildCount() <= 0) {
            return cellViews;
        }
        int count = container.getChildCount();
        for (int i = 0; i < count; i++) {
            View childView = container.getChildAt(i);
            if (childView != null && childView instanceof InsuranceCellView) {
                cellViews.add((InsuranceCellView) childView);
            }
        }
        return cellViews;
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onEventMainThread(CancelCalculating event) {
        if (mInsuranceCellViewUpdater != null) {
            mInsuranceCellViewUpdater.stopWebViewLoading();
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onEventMainThread(NormalRiskCompleteEvent event) {
        if (event != null && event.insuranceView == this) {
            if (mInsuranceCellViewUpdater != null) {
                mInsuranceCellViewUpdater.clearInsuranceViewRef();
            }

            post(new Runnable() {
                @Override
                public void run() {
                    ExemptDao mExemptDao = new ExemptDao(getContext(), InsuranceView.this);
                    List<InsuranceCellView> cellViews = getCellViews();
                    for (InsuranceCellView item : cellViews) {
                        if (item.getData().isExemption()) {
                            ExemptTask newTask = new ExemptTask();
                            newTask.applicant = applicantView.getCustomer();
                            newTask.insured = insuredView.getCustomer();
                            newTask.cellView = item;
                            mExemptDao.start(newTask);
                        }
                    }
                }
            });
        }
    }

    private void updateCellView(List<InsuranceCellView> cellViews) {
        mInsuranceCellViewUpdater.updateCellViewExceptExempt(cellViews, mApplicantPerson,
                mInsuredPerson, applicantView.getCustomer(), insuredView.getCustomer(), this);
    }

    public void setForMoreInsuredViewTitle(String title) {
        if (proposalHeader != null) {
            proposalHeader.setTitle(title);
        }
    }

    private InsuredView insuredView;

    public void setCorrespondingInsuredView(InsuredView insuredView) {
        this.insuredView = insuredView;
    }

    private ApplicantView applicantView;

    public void setCorrespondingApplicantView(ApplicantView applicantView) {
        this.applicantView = applicantView;
    }

    public ApplicantEntity getApplicantPerson() {
        return mApplicantPerson;
    }

    public InsuredEntity getInsuredPerson() {
        return mInsuredPerson;
    }

    public InsuranceCellViewUpdater getInsuranceCellViewUpdater() {
        return mInsuranceCellViewUpdater;
    }
}
